﻿//This is for showing the usage of SVD in solving linear equations problems.
//The equa is like form  AX=B. B!=[0].A is a m*n Matrix, m>=n.
//For now we set a simple like like A is a 3*2 Matrix.
//info:   Matrix can be added  and minus.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DotNumerics;
using DotNumerics.LinearAlgebra;


public class SVDAnalysis : MonoBehaviour {

	SingularValueDecomposition svd = new SingularValueDecomposition();

	//[SerializeField]
	public Matrix MatA;   //The para mat which is to be SVD decomposed;
	Matrix U;
	Matrix S;
	Matrix Vt;

	Matrix MatX_Result ;
	Matrix MatA_mu_X_Result ;

	public Matrix MatB;   //The B vector contains destination values.


	int MatA_Row_m=3;
	int MatA_Col_n=2;


	public void InitMatrix()
	{
		MatA=new Matrix(MatA_Row_m, MatA_Col_n);
		MatA[0,0]=1;	MatA[0,1]=3;
		MatA[1,0]=2;	MatA[1,1]=7;
		MatA[2,0]=5;	MatA[2,1]=4;

		MatB=new Matrix(MatA_Row_m,1);
		MatB[0,0]=7;
	    MatB[1,0]=4;
		MatB[2,0]=3;
	}


	public void SVDProcess()
	{
		svd.ComputeSVD(MatA, out this.S, out this.U, out this.Vt);
	}

	public void CalculateResult()
	{
		Matrix Ut_B=(U.Transpose())*MatB;
		Debug.Log("Ut*B  "+Ut_B[0,0]+"   "+Ut_B[1,0]+"   "+Ut_B[2,0]+"   ");

		Matrix Mat_y = new Matrix(Vt.ColumnCount,1);

		for(int i=0;i<Vt.ColumnCount;i++)
		{
				Mat_y[i,0]=Ut_B[i,0]/S[i,i];
		}

		MatX_Result = new Matrix(Vt.ColumnCount,1);
		MatA_mu_X_Result= new Matrix(Vt.ColumnCount,1);
		MatX_Result=Vt.Transpose()*Mat_y;

		MatA_mu_X_Result=MatA*MatX_Result;
	}


	// Use this for initialization
	void Start () {
		InitMatrix();
		SVDProcess();
		CalculateResult();
	}
	
	// Update is called once per frame
	void Update () {
		
	}



	void OnGUI()
	{
		GUILayout.Label("The values of U Matrix ");
		if(U!=null)
		{
			for(int i=0;i<U.RowCount;i++)
			{
				string str=string.Empty;
				for(int j=0;j<U.ColumnCount;j++)
				{
					str+=U[i,j].ToString("0.0000")+"  ";
				}

				GUILayout.Label(str);
			}	
		}

		GUILayout.Label("  ");

		GUILayout.Label("The values of Result X Vectors ");
		if(MatX_Result!=null)
		{
			for(int i=0;i<MatX_Result.RowCount;i++)
			{
				GUILayout.Label((MatX_Result[i,0]).ToString());
			}	
		}
		GUILayout.Label("  ");

		GUILayout.Label("The values of Result X Vectors ");
		if(MatA_mu_X_Result!=null)
		{
			for(int i=0;i<MatA_mu_X_Result.RowCount;i++)
			{
				GUILayout.Label((MatA_mu_X_Result[i,0]).ToString());
			}	
		}


	}

}
